package com.test.com.bluetoothchatandroid.utils;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.orhanobut.logger.Logger;
import com.test.com.bluetoothchatandroid.callback.BluetoothChatCallback;
import com.test.com.bluetoothchatandroid.global.BluetoothState;
import com.test.com.bluetoothchatandroid.global.ChatConstant;
import com.test.com.bluetoothchatandroid.thread.AcceptThread;
import com.test.com.bluetoothchatandroid.thread.ConnectThread;
import com.test.com.bluetoothchatandroid.thread.ConnectedThread;

/**
 * Created by ${cs} on 2018/4/20.
 */

public class BluetoothChatHelper {

	private final BluetoothAdapter mAdapter;
	private ConnectedThread mConnectedThread;
	private ConnectThread mConnectThread;
	private AcceptThread mAcceptThread;
	private BluetoothState mState;
	private BluetoothChatCallback<byte[]> mChatCallback;
	private final Handler mHandler = new Handler(Looper.getMainLooper()){
		@Override
		public void handleMessage(Message msg) {
			if (msg == null || msg.obj == null){
				return;
			}

			switch (msg.what) {
				case ChatConstant.MESSAGE_STATE_CHANGE:
					if (mChatCallback != null) {
						mChatCallback.connectStateChange((BluetoothState) msg.obj);
					}
					break;
				case ChatConstant.MESSAGE_WRITE:
					if (mChatCallback != null) {
						mChatCallback.writeData((byte[]) msg.obj, 0);
					}
					break;
				case ChatConstant.MESSAGE_READ:
					if (mChatCallback != null) {
						mChatCallback.readData((byte[]) msg.obj, 0);
					}
					break;
				case ChatConstant.MESSAGE_DEVICE_NAME:
					if (mChatCallback != null) {
						mChatCallback.setDeviceName((String) msg.obj);
					}
					break;
				case ChatConstant.MESSAGE_TOAST:
					if (mChatCallback != null) {
						mChatCallback.showMessage((String) msg.obj, 0);
					}
					break;
				default:
					Logger.d("Nothing choose....");
					break;
			}

		}
	};


	public BluetoothChatHelper(BluetoothChatCallback<byte[]> chatCallback) {
		mAdapter = BluetoothAdapter.getDefaultAdapter();
		mState = BluetoothState.STATE_NONE;
		this.mChatCallback = chatCallback;
	}

	public synchronized BluetoothState getState(){
		return mState;
	}

	public BluetoothAdapter getAdapter(){
		return mAdapter;
	}

	public Handler getHandler(){
		return mHandler;
	}

	private synchronized BluetoothChatHelper setState(BluetoothState state){
		mState = state;
		mHandler.obtainMessage(ChatConstant.MESSAGE_STATE_CHANGE,-1,-1,state).sendToTarget();
		return this;
	}

	public ConnectedThread getConnectedThread(){
		return mConnectedThread;
	}

	public BluetoothChatHelper setConnectThread(ConnectThread mConnectThread){
		this.mConnectThread = mConnectThread;
		return this;
	}

	public synchronized void start(boolean secure){
		if (mConnectedThread != null){
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		if (mConnectThread != null){
			mConnectThread.cancel();
			mConnectThread = null;
		}

		setState(BluetoothState.STATE_LISTEN);
		if (mAcceptThread == null){
			if (secure){
				Logger.d("未初始化 安全线程 开始初始化....");
			}else {
				Logger.d("未初始化 非安全线程 开始初始化....");
			}

			mAcceptThread = new AcceptThread(this,secure);
			mAcceptThread.start();
		}
	}

	public void connectionFailed() {
		mHandler.obtainMessage(ChatConstant.MESSAGE_TOAST,-1,-1,"无法连接设备").sendToTarget();
		this.start(false);
	}

	public void connectionLost(){
		mHandler.obtainMessage(ChatConstant.MESSAGE_TOAST,-1,-1,"设备连接丢失").sendToTarget();
		this.start(false);
	}
	public synchronized void connect(BluetoothDevice device, boolean secure) {
		Logger.d("connect to: " + device);
		if (mState == BluetoothState.STATE_CONNECTING) {
			if (mConnectThread != null) {
				mConnectThread.cancel();
				mConnectThread = null;
			}
		}

		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		mConnectThread = new ConnectThread(this, device, secure);
		mConnectThread.start();
		setState(BluetoothState.STATE_CONNECTING);
	}


	public synchronized void connected(BluetoothSocket mSocket,
	                      BluetoothDevice mDevice, final String mSocketType) {
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}

		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		if (mAcceptThread != null){
			mAcceptThread.cancel();
			mAcceptThread = null;
		}

		mConnectedThread = new ConnectedThread(this, mSocket, mSocketType);
		mConnectedThread.start();

		mHandler.obtainMessage(ChatConstant.MESSAGE_DEVICE_NAME, -1, -1, mDevice.getName()).sendToTarget();
		setState(BluetoothState.STATE_CONNECTED);

	}

	public synchronized void stop() {
		Logger.d("server stop");
		if (mConnectThread != null) {
			mConnectThread.cancel();
			mConnectThread = null;
		}

		if (mConnectedThread != null) {
			mConnectedThread.cancel();
			mConnectedThread = null;
		}

		if (mAcceptThread != null) {
			mAcceptThread.cancel();
			mAcceptThread = null;
		}

		setState(BluetoothState.STATE_NONE);
	}

	public void write(byte[] out) {
		ConnectedThread r;
		synchronized (this) {
			if (mState != BluetoothState.STATE_CONNECTED)
				return;
			r = mConnectedThread;
		}
		r.write(out);
	}


}
